import 'package:dio/dio.dart';
import 'package:food_hub_app/config/app_config.dart';
import 'package:food_hub_app/utils/sp_util.dart';
import 'package:food_hub_app/widgets/common/index.dart';

import 'log_util.dart';

class HttpUtil {
  static final HttpUtil _instance = HttpUtil._internal();

  factory HttpUtil() => _instance;

  late Dio _dio;

  // 请求头配置
  Map<String, dynamic> headers = {
    'Content-Type': 'application/json;charset=UTF-8',
    'Accept': 'application/json',
  };

  // 超时时间
  final int timeout = 5;

  HttpUtil._internal() {
    // 初始化Dio实例
    BaseOptions options = BaseOptions(
      baseUrl: AppConfig.baseApiUrl,
      connectTimeout: Duration(seconds: timeout),
      receiveTimeout: Duration(seconds: timeout),
      headers: headers,
    );

    _dio = Dio(options);

    // 添加请求拦截器
    _dio.interceptors.add(
      InterceptorsWrapper(
        onRequest: (options, handler) {
          logger.d("请求URL: ${options.uri}");
          if (options.data != null) {
            logger.d("请求参数: ${options.data}");
          }

          if (SPUtil.getString('token').isNotEmpty) {
            options.headers['satoken'] = SPUtil.getString('token');
          }
          return handler.next(options);
        },
      ),
    );

    // 添加响应拦截器
    _dio.interceptors.add(
      InterceptorsWrapper(
        onResponse: (response, handler) {
          logger.d("响应状态码: ${response.statusCode}");
          // logger.d("响应数据: ${response.data}");
          return handler.next(response);
        },
      ),
    );

    // 添加错误拦截器
    _dio.interceptors.add(
      InterceptorsWrapper(
        onError: (DioException e, handler) {
          _handleError(e);
          return handler.next(e);
        },
      ),
    );
  }

  // 基础请求方法（处理所有类型的请求）
  Future<T> _request<T>(
    String path, {
    required String method,
    dynamic data,
    Map<String, dynamic>? queryParameters,
    T Function(dynamic data)? converter,
  }) async {
    try {
      Response response = await _dio.request(
        path,
        data: data,
        queryParameters: queryParameters,
        options: Options(method: method),
      );

      // 处理响应数据
      if (converter != null) {
        return converter(response.data);
      }

      // 没有转换器时尝试直接返回（可能不安全，建议提供转换器）
      return response.data;
    } catch (e) {
      rethrow;
    }
  }

  // GET请求
  Future<T> get<T>(
    String path, {
    Map<String, dynamic>? queryParameters,
    T Function(dynamic data)? converter,
  }) => _request(
    path,
    method: "GET",
    queryParameters: queryParameters,
    converter: converter,
  );

  // POST请求
  Future<T> post<T>(
    String path, {
    dynamic data,
    Map<String, dynamic>? queryParameters,
    T Function(dynamic data)? converter,
  }) => _request(
    path,
    method: "POST",
    data: data,
    queryParameters: queryParameters,
    converter: converter,
  );

  // PUT请求
  Future<T> put<T>(
    String path, {
    dynamic data,
    Map<String, dynamic>? queryParameters,
    T Function(dynamic data)? converter,
  }) => _request(
    path,
    method: "PUT",
    data: data,
    queryParameters: queryParameters,
    converter: converter,
  );

  // DELETE请求
  Future<T> delete<T>(
    String path, {
    dynamic data,
    Map<String, dynamic>? queryParameters,
    T Function(dynamic data)? converter,
  }) => _request(
    path,
    method: "DELETE",
    data: data,
    queryParameters: queryParameters,
    converter: converter,
  );

  // 文件上传
  Future<dynamic> upload(
    String path,
    String filePath, {
    Map<String, dynamic>? queryParameters,
  }) async {
    try {
      FormData formData = FormData.fromMap({
        'file': await MultipartFile.fromFile(filePath),
      });

      Response response = await _dio.post(
        path,
        data: formData,
        queryParameters: queryParameters,
      );
      return response.data;
    } catch (e) {
      _handleError(e);
      rethrow;
    }
  }

  // 错误处理
  void _handleError(dynamic error) {
    String errorMessage = '未知错误';
    if (error is DioException) {
      switch (error.type) {
        case DioExceptionType.connectionTimeout:
          errorMessage = '连接超时，请检查网络连接';
          break;
        case DioExceptionType.sendTimeout:
          errorMessage = '发送超时，请检查网络连接';
          break;
        case DioExceptionType.receiveTimeout:
          errorMessage = '接收超时，请检查网络连接';
          break;
        case DioExceptionType.cancel:
          errorMessage = '请求已取消';
          break;
        case DioExceptionType.badCertificate:
          errorMessage = '证书验证失败';
          break;
        case DioExceptionType.badResponse:
          // 处理HTTP响应错误（4xx, 5xx）
          final statusCode = error.response?.statusCode ?? 0;
          final responseData = error.response?.data;

          if (responseData is Map<String, dynamic> && responseData.containsKey('message')) {
            // 服务器返回了自定义错误消息
            errorMessage = responseData['message']?.toString() ?? '未知错误';
          } else {
            errorMessage = _getHttpErrorMessage(statusCode);
          }
          break;
        case DioExceptionType.connectionError:
          errorMessage = '网络连接错误，请检查网络设置';
          break;
        case DioExceptionType.unknown:
          if (error.error != null) {
            errorMessage = '未知错误: ${error.error.toString()}';
          }
          errorMessage =  '发生未知错误';
          break;
      }
    } else {
      errorMessage = '非Dio错误: $error';
    }

    print(errorMessage);
    showErrorToast(errorMessage);
  }

  String _getHttpErrorMessage(int statusCode) {
    // 根据HTTP状态码返回对应的错误消息
    switch (statusCode) {
      case 400: return '错误请求，请检查参数';
      case 401: return '未授权，请登录';
      case 403: return '禁止访问，权限不足';
      case 404: return '资源不存在';
      case 405: return '方法不允许';
      case 408: return '请求超时';
      case 500: return '服务器内部错误';
      case 502: return '网关错误';
      case 503: return '服务不可用';
      case 504: return '网关超时';
      default: return 'HTTP错误: $statusCode';
    }
  }
}
